﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Client.Connecting;
using MQTTnet.Client.Disconnecting;
using MQTTnet.Client.Options;
using MQTTnet.Client.Receiving;

namespace MQTTService
{
    public class MQTTClients
    {
        private IMqttClient _client;
        /// <summary>
        /// 连接回调
        /// </summary>
        /// <param name="ClientId">客户端连接Id</param>
        /// <param name="Version">版本号</param>
        public delegate void ClientConnected(bool IsConn);
        public ClientConnected ClientConnecteds;
        /// <summary>
        /// 断线回调
        /// </summary>
        /// <param name="ClientId">客户端连接Id</param>
        public delegate void ClientDisconnected(bool IsDisConn);
        public ClientDisconnected ClientDisconnecteds;
        /// <summary>
        /// 消息负荷
        /// </summary>
        /// <param name="ClientId">客户端连接Id</param>
        /// <param name="Topic">消息主题</param>
        /// <param name="Payload">消息体</param>
        /// <param name="QualityOfServiceLevel">QOS</param>
        /// <param name="Retain">保留</param>
        public delegate void MessageReceived(string ClientId, string Topic, string Payload, string QualityOfServiceLevel, bool Retain);
        public MessageReceived MessageReceiveds;
        private MqttClientConnectResultCode? MQTTState=null;
        #region MQTT操作方法
        /// <summary>
        /// 初始化连接
        /// </summary>
        /// <param name="url">MQTT服务器地址</param>
        /// <param name="port">MQTT端口</param>
        public bool InitClient(string url, int port = 1883)
        {
            try
            {
                string ClientId = Guid.NewGuid().ToString("N");
                var options = new MqttClientOptions()
                {
                    ClientId = ClientId
                };
                options.Credentials = new MqttClientCredentials { 
                Username="admin",
                Password= Encoding.UTF8.GetBytes("123456")
            };
                options.ChannelOptions = new MqttClientTcpOptions()
                {
                    Server = url,
                    Port = port
                };
                options.CleanSession = true;
                options.KeepAlivePeriod = TimeSpan.FromSeconds(100);
                if (_client != null)
                {
                    _client.DisconnectAsync();
                    _client = null;
                }
                _client = new MqttFactory().CreateMqttClient();
                _client.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(_client_ApplicationMessageReceived);
                _client.ConnectedHandler = new MqttClientConnectedHandlerDelegate(_client_Connected);
                _client.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(_client_Disconnected);
                _client.ConnectAsync(options);
                while (MQTTState==null)
                {
                    System.Threading.Thread.Sleep(100);
                }
                return MQTTState== MqttClientConnectResultCode.Success;
            }
            catch(Exception ex)
            {
                return false;
            }
        }
        /// <summary>
        /// 反初始化连接
        /// </summary>
        public bool UnInitClient()
        {
            try
            {
                if (_client != null)
                {
                    _client.DisconnectAsync();
                    return !_client.IsConnected;
                }
                else
                {
                    return true;
                }
            }
            catch (Exception ex)
            {
                return false;
            }

        }
        /// <summary>
        /// 订阅主题
        /// </summary>
        /// 订阅参数信息仅配置 
        /// IsCheck 是否使用本主题
        /// Topics 推送/订阅主题
        /// QOSEnum 订阅推送次数
        /// <param name="topic">订阅参数信息</param>
        [Obsolete]
        public void SubscribeTopics(List<TopicsM> topic)
        {
            try
            {
                List<TopicsM> tops = topic.Where(s => s.IsCheck = true).ToList();
                List<TopicFilter> topics = ConvertDatas.ConvertData.ConvertTopicFilter(tops);
                _client.SubscribeAsync(topics.ToArray());
            }
            catch (Exception ex)
            {}
           
        }
        /// <summary>
        /// 取消订阅主题
        /// </summary>
        /// <param name="topics">主题名称</param>
        [Obsolete]
        public void UnSubscribeTopics(List<string> topics)
        {
            try
            {
                _client.UnsubscribeAsync(topics.ToArray());
            }
            catch (Exception ex)
            {
            }
        }
        /// <summary>
        /// 消息推送
        /// </summary>
        /// <param name="topics">推送参数信息</param>
        [Obsolete]
        public void Publish_Message(TopicsM topics)
        {
            try
            {
                if (_client!=null)
                {
                    string topic = topics.Topics;
                    string content = topics.Describe;
                    MqttApplicationMessage msg = new MqttApplicationMessage
                    {
                        Topic = topic,
                        Payload = Encoding.UTF8.GetBytes(content),
                        QualityOfServiceLevel = (MQTTnet.Protocol.MqttQualityOfServiceLevel)topics.QOSEnum,
                        Retain = topics.Retain
                    };
                    _client.PublishAsync(msg);
                }
            }
            catch (Exception ex)
            {

            }
        }

        #endregion

        #region 数据回调
        /// <summary>
        /// 客户端与服务端断开连接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _client_Disconnected(MqttClientDisconnectedEventArgs e)
        {
            ClientDisconnecteds(e.ClientWasConnected);
        }
        /// <summary>
        /// 客户端与服务端建立连接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void _client_Connected(MqttClientConnectedEventArgs e)
        {
            string str= e.AuthenticateResult.ReasonString;
            MQTTState = e.AuthenticateResult.ResultCode;
            ClientConnecteds(e.AuthenticateResult.ResultCode == MqttClientConnectResultCode.Success);
            Console.WriteLine("与服务端建立连接");
        }
        /// <summary>
        /// 客户端收到消息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _client_ApplicationMessageReceived(MqttApplicationMessageReceivedEventArgs e)
        {
            MessageReceiveds(e.ClientId, e.ApplicationMessage.Topic, Encoding.UTF8.GetString(e.ApplicationMessage.Payload), e.ApplicationMessage.QualityOfServiceLevel.ToString(), e.ApplicationMessage.Retain);
            //WriteToStatus("收到来自客户端" + e.ClientId + "，主题为" + e.ApplicationMessage.Topic + "的消息：" + Encoding.UTF8.GetString(e.ApplicationMessage.Payload));
        }
        #endregion
    }
}
